//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "Utils/Texture/Image/Image.h"
#include "Shared/Resources/ResourceFileInfo.h"

namespace Engine
{
namespace Utils
{

#	include "Shared/Resources/ImageHeader.h"



	//
	// Image Saver
	//

	struct ImageSaver
	{
	// methods
	public:
		static bool Save (uni_c_string filename, const Image &img);
		static bool Save (const WFilePtr &file, const Image &img);


	private:
		static bool _SaveTex (const WFilePtr &file, const Image &img);
	};


	
	// Save
	inline bool ImageSaver::Save (uni_c_string filename, const Image &img)
	{
		WFilePtr	file;
		CHECK_ERR( (file = File::HddWFile::New( filename )).IsNotNull() );

		return Save( file, img );
	}


	// Save
	inline bool ImageSaver::Save (const WFilePtr &file, const Image &img)
	{
		return _SaveTex( file, img );
	}
		

	// _SaveTex
	inline bool ImageSaver::_SaveTex (const WFilePtr &file, const Image &img)
	{
		typedef array< ImageHeader::MipmapInfo, TFastCopyStrategy< ImageHeader::MipmapInfo > >	mipmap_info_array_t;

		ImageHeader	header;

		header.width		= img.Dimension().x;
		header.height		= img.Dimension().y;
		header.depth		= img.Dimension().z;
		header.layers		= 0;
		header.mipmaps		= img.NumMipmaps();
		header.pixelFormat	= img.PixelFormat();

		CHECK_ERR( header.mipmaps > 0 );

		mipmap_info_array_t		mipmaps;
		usize					data_size = 0;
		usize					level	  = 0;

		mipmaps.Resize( header.mipmaps, false );

		FOR( i, mipmaps )
		{
			if ( not img.HasMipmapLevel( level ) )
			{
				--i;
				++level;
				continue;
			}

			mipmaps[i].level  = level;
			mipmaps[i].offset = data_size;
			mipmaps[i].size	  = img.GetMipmapData( level ).Size();
			data_size		 += mipmaps[i].size;
			++level;
		}

		header.dataSize	= data_size;

		level = 0;

		bool	res = true;

		RESFILE_WRITE_HEADER( file, TextureFileInfo );

		res &= file->Write( header );
		res &= file->Write( mipmaps.ptr(), mipmaps.Size() );

		while ( level < (uint)header.mipmaps )
		{
			const uni_binbuffer_t	buf = img.GetMipmapData( level );

			res &= file->Write( buf.ptr(), buf.Size() );

			++level;
		}

		CHECK_ERR( res );
		return true;
	}


}	// Utils
}	// Engine